package com.comleader.ldmapdownload.util;

import com.alibaba.fastjson.JSONArray;
import com.comleader.ldmapdownload.bean.Hopper;
import com.graphhopper.GHRequest;
import com.graphhopper.GHResponse;
import com.graphhopper.GraphHopper;
import com.graphhopper.PathWrapper;
import com.graphhopper.reader.osm.GraphHopperOSM;
import com.graphhopper.routing.util.EncodingManager;
import com.graphhopper.util.GPXEntry;
import com.graphhopper.util.shapes.GHPoint;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import javax.annotation.PostConstruct;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;

/**
 * @author ：杨浩毅 (1759)
 * @date ：2020/9/8 17:20
 */
@Component
@PropertySource(value = {"classpath:config/download-map.properties"}, encoding = "UTF-8")
public class HopperUtils {

    @Value("${map.oms.pbf}")
    private String OMS_PATH_CONFIG;

    private static String OMS_PATH;

    @Value("${map.oms.graphhopper}")
    private String HOPPER_PATH_CONFIG;

    private static String HOPPER_PATH;

    //当容器实例化当前受管Bean时@PostConstruct注解的方法会被自动触发，借此来实现静态变量初始化
    @PostConstruct
    public void init() {
        this.OMS_PATH = OMS_PATH_CONFIG;
        this.HOPPER_PATH = HOPPER_PATH_CONFIG;
    }

    /**
     * 路网数据源
     * @return 经过路径规划算法算过的文件位置
     */
    public static GraphHopper DataSource(Hopper hopper){
        // 创建一个GraphHopper实例
        GraphHopper ghhopper = new GraphHopperOSM().forServer();
        ghhopper.setDataReaderFile(OMS_PATH);
        // 在哪里存储graphhopper文件？
        String path=HOPPER_PATH+"/"+hopper.getWeighting()+"/"+hopper.getVehicle();
        ghhopper.setGraphHopperLocation(path);
        ghhopper.setEncodingManager(new EncodingManager(hopper.getVehicle()));
        // 现在，如果导入，则可能需要几分钟，或者加载需要几秒钟
        // 当然这取决于您导入的区域
        ghhopper.importOrLoad();
        return ghhopper;
    }

    /**
     * 坐标点集合的路线规划
     * @param ghPoints 坐标点集合
     * @param hopper 路径规划配置信息
     * @return 路径规划对象
     */
    public static PathWrapper path(List<GHPoint> ghPoints,Hopper hopper){
        // 设置默认值
        if (hopper == null){
            hopper = new Hopper(Global.Vehicle.THREE,Global.Weighting.ZERO);
        }
        if (StringUtils.isEmpty(hopper.getVehicle())){
            hopper.setVehicle(Global.Vehicle.THREE);
        }
        if (StringUtils.isEmpty(hopper.getWeighting())){
            hopper.setWeighting(Global.Weighting.ZERO);
        }
        GHRequest req = new GHRequest(
                ghPoints).
                setWeighting(hopper.getWeighting()).
                setVehicle(hopper.getVehicle()).
                setLocale(Locale.CHINA);
           GHResponse rsp = DataSource(hopper).route(req);
        // 首先检查错误
        if (rsp.hasErrors()) {
            rsp.getErrors();
        }
        // 使用最佳路径，请参阅GHResponse类以了解更多可能性。
        PathWrapper path = rsp.getBest();
        return path;
    }

    public static List<GHPoint> points(String list) {
        String s = list.replace("\"", "").replace("\"", "");
        List<GHPoint> points = JSONArray.parseArray(s, GHPoint.class);
        List<GHPoint> pointLs = new ArrayList<>();
        for (GHPoint point : points) {
            GHPoint resGpoint = TransLocationUtil.gcj2wgs(point);
            pointLs.add(resGpoint);
        }
        return pointLs;
    }

    public static List gpxList(List<GPXEntry> list) {
        List points = new ArrayList<>();
        for (GPXEntry gpxEntry : list) {
            GHPoint transform = TransLocationUtil.transform(gpxEntry.lon, gpxEntry.lat);
            Point point2 = new Point(transform.getLon(), transform.getLat(), gpxEntry.ele, gpxEntry.getTime());
            points.add(point2);
        }
        return points;
    }
}
